/* * Copyright 2013 Vishwa Patel * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License in the 'assets' directory of this * application or at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.vishwa.pinit; import java.io.IOException; import java.util.List; import java.util.Locale; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicResponseHandler; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.MatrixCursor; import android.location.Address; import android.location.Geocoder; import android.net.Uri; import android.net.http.AndroidHttpClient; import android.provider.BaseColumns; public class LocationSuggestionProvider extends ContentProvider { private Geocoder mGeocoder; public static final String AUTHORITY = "com.vishwa.pinit.search_suggestion_provider"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/search"); private static final int SEARCH_SUGGEST = 1; private static final AndroidHttpClient mAndroidHttpClient = AndroidHttpClient.newInstance(LocationSuggestionProvider.class.getName()); private static final UriMatcher uriMatcher; private static final String[] SEARCH_SUGGEST_COLUMNS = { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID }; private String mGoogleGeocodingEndpoint = "http://maps.googleapis.com/maps/api/geocode/json?address="; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST); } @Override public int delete(Uri uri, String arg1, String[] arg2) { throw new UnsupportedOperationException(); } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: return SearchManager.SUGGEST_MIME_TYPE; default: throw new IllegalArgumentException("Unknown URL " + uri); } } @Override public Uri insert(Uri uri, ContentValues arg1) { throw new UnsupportedOperationException(); } @Override public boolean onCreate() { return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch (uriMatcher.match(uri)) { case SEARCH_SUGGEST: String query = uri.getLastPathSegment(); MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1); if(Geocoder.isPresent()) { try { mGeocoder = new Geocoder(getContext(), Locale.ENGLISH); List<Address> addressList = mGeocoder.getFromLocationName(query, 5); for(int i = 0; i < addressList.size(); i++) { Address address = addressList.get(i); StringBuilder fullAddress = new StringBuilder(); for(int j = 1; j < address.getMaxAddressLineIndex(); j++) { fullAddress.append(address.getAddressLine(j)); } cursor.addRow(new String[] {Integer.toString(i), address.getAddressLine(0).toString(), fullAddress.toString(), address.getLatitude()+","+address.getLongitude()}); } return cursor; } catch (IllegalArgumentException e) { return getLocationSuggestionsUsingAPI(query, cursor); } catch (IOException e) { return getLocationSuggestionsUsingAPI(query, cursor); } } default: throw new IllegalArgumentException("Unknown Uri: " + uri); } } private MatrixCursor getLocationSuggestionsUsingAPI(String query, MatrixCursor cursor){ String transformedQuery = query.replace(" ", "+"); String queryUrl = mGoogleGeocodingEndpoint + transformedQuery + "&sensor=false"; try { JSONObject apiResponse = new JSONObject(mAndroidHttpClient.execute(new HttpGet(queryUrl), new BasicResponseHandler())); JSONArray results = (JSONArray) apiResponse.get("results"); for(int i = 0; i < results.length(); i++) { String formattedAddress; JSONObject result = results.getJSONObject(i); if(result.has("formatted_address")) { formattedAddress = result.getString("formatted_address"); if(result.has("geometry")) { JSONObject geometry = result.getJSONObject("geometry"); if(geometry.has("location")) { JSONObject location = geometry.getJSONObject("location"); double latitude = location.getDouble("lat"); double longitude = location.getDouble("lng"); cursor.addRow(new String[] {Integer.toString(i), formattedAddress, "", latitude+","+longitude}); } } } } return cursor; } catch (ClientProtocolException e) { cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""}); return cursor; } catch (JSONException e) { cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""}); return cursor; } catch (IOException e) { cursor.addRow(new String[] {"0", "Search is not available currently", "Try again later.", ""}); return cursor; } } @Override public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) { throw new UnsupportedOperationException(); } }